home *** CD-ROM | disk | FTP | other *** search
/ SPACE 2 / SPACE - Library 2 - Volume 1.iso / misc / 39 / lev.c < prev    next >
Encoding:
C/C++ Source or Header  |  1986-07-17  |  8.2 KB  |  360 lines

  1. /* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */
  2. /* lev.c - version 1.0.3 */
  3.  
  4. #include <stdio.h>
  5. #include "hack.h"
  6. #include "mkroom.h"
  7. extern struct monst *restmonchn();
  8. extern struct obj *restobjchn();
  9. extern struct obj *billobjs;
  10. extern char *itoa();
  11. extern char SAVEF[];
  12. extern int hackpid;
  13. extern xchar dlevel;
  14. extern char nul[];
  15.  
  16. #ifndef NOWORM
  17. #include    "wseg.h"
  18. extern struct wseg *wsegs[32], *wheads[32];
  19. extern long wgrowtime[32];
  20. #endif NOWORM
  21.  
  22. boolean level_exists[MAXLEVEL+1];
  23.  
  24. savelev(fd,lev)
  25. int fd;
  26. xchar lev;
  27. {
  28. #ifdef TOS
  29.     short tlev;
  30. #endif
  31. #ifndef NOWORM
  32.     register struct wseg *wtmp, *wtmp2;
  33.     register tmp;
  34. #endif NOWORM
  35.     if(fd < 0) panic("Save on bad file!");    /* impossible */
  36.     if(lev >= 0 && lev <= MAXLEVEL)
  37.         level_exists[lev] = TRUE;
  38. #ifdef MSDOS
  39. #ifndef TOS
  40.     setmode(fd,O_BINARY);
  41. #endif
  42. #endif MSDOS
  43.     bwrite(fd,(char *) &hackpid,sizeof(hackpid));
  44. #ifdef TOS
  45.     tlev=lev;
  46.     bwrite(fd,(char *) &tlev,sizeof(tlev));
  47. #else
  48.     bwrite(fd,(char *) &lev,sizeof(lev));
  49. #endif
  50.     bwrite(fd,(char *) levl,sizeof(levl));
  51.     bwrite(fd,(char *) &moves,sizeof(long));
  52.     bwrite(fd,(char *) &xupstair,sizeof(xupstair));
  53.     bwrite(fd,(char *) &yupstair,sizeof(yupstair));
  54.     bwrite(fd,(char *) &xdnstair,sizeof(xdnstair));
  55.     bwrite(fd,(char *) &ydnstair,sizeof(ydnstair));
  56.     savemonchn(fd, fmon);
  57.     savegoldchn(fd, fgold);
  58.     savetrapchn(fd, ftrap);
  59.     saveobjchn(fd, fobj);
  60.     saveobjchn(fd, billobjs);
  61.     billobjs = 0;
  62.     save_engravings(fd);
  63. #ifndef QUEST
  64.     bwrite(fd,(char *) rooms,sizeof(rooms));
  65.     bwrite(fd,(char *) doors,sizeof(doors));
  66. #endif QUEST
  67.     fgold = 0;
  68.     ftrap = 0;
  69.     fmon = 0;
  70.     fobj = 0;
  71. #ifndef NOWORM
  72.     bwrite(fd,(char *) wsegs,sizeof(wsegs));
  73.     for(tmp=1; tmp<32; tmp++){
  74.         for(wtmp = wsegs[tmp]; wtmp; wtmp = wtmp2){
  75.             wtmp2 = wtmp->nseg;
  76.             bwrite(fd,(char *) wtmp,sizeof(struct wseg));
  77.         }
  78.         wsegs[tmp] = 0;
  79.     }
  80.     bwrite(fd,(char *) wgrowtime,sizeof(wgrowtime));
  81. #endif NOWORM
  82. }
  83.  
  84. bwrite(fd,loc,num)
  85. register fd;
  86. register char *loc;
  87. register unsigned num;
  88. {
  89. /* lint wants the 3rd arg of write to be an int; lint -p an unsigned */
  90.     if(write(fd, loc, (int) num) != num)
  91.         panic("cannot write %u bytes to file #%d", num, fd);
  92. }
  93.  
  94. saveobjchn(fd,otmp)
  95. register fd;
  96. register struct obj *otmp;
  97. {
  98.     register struct obj *otmp2;
  99.     unsigned xl;
  100.     int minusone = -1;
  101.  
  102.     while(otmp) {
  103.         otmp2 = otmp->nobj;
  104.         xl = otmp->onamelth;
  105.         bwrite(fd, (char *) &xl, sizeof(int));
  106.         bwrite(fd, (char *) otmp, xl + sizeof(struct obj));
  107.         free((char *) otmp);
  108.         otmp = otmp2;
  109.     }
  110.     bwrite(fd, (char *) &minusone, sizeof(int));
  111. }
  112.  
  113. #ifdef MSDOS
  114. /* We don't want to save any pointers in any files, so convert
  115.  * the pointers to indices before writing the monsters to disk -dgk
  116.  */
  117. savemonchn(fd,mtmp)
  118. register fd;
  119. register struct monst *mtmp;
  120. {
  121.     register struct monst *mtmp2;
  122.     unsigned xl;
  123.     int minusone = -1;
  124.     struct permonst *permonstp;
  125.     int monsindex;
  126.     extern struct permonst li_dog, dog, la_dog;
  127. #ifdef DEBUG
  128.     char trace[80];
  129. #endif
  130.     while(mtmp) {
  131.         mtmp2 = mtmp->nmon;
  132.         xl = mtmp->mxlth + mtmp->mnamelth;
  133.         bwrite(fd, (char *) &xl, sizeof(int));
  134.         /* store an index where the pointer used to be */
  135.         permonstp = mtmp->data;
  136. #ifdef DEBUG
  137.         sprintf(trace,"mtmp=%x perm=%x ",mtmp,permonstp);
  138.         printer(trace);
  139. #endif
  140.         if (permonstp == &li_dog)
  141.             monsindex = -1;        /* special fake index */
  142.         else if (permonstp == &dog)
  143.             monsindex = -2;        /* special fake index */
  144.         else if (permonstp == &la_dog)
  145.             monsindex = -3;        /* special fake index */
  146.         else
  147.             monsindex = permonstp - &mons[0];
  148.         *((int *)&mtmp->data) = monsindex;
  149. #ifdef DEBUG
  150.         sprintf(trace,"monsindex=%x\n",monsindex);
  151.         printer(trace);
  152. #endif
  153.         bwrite(fd, (char *) mtmp, xl + sizeof(struct monst));
  154.         mtmp->data = permonstp;        /* restore the pointer */
  155.         if(mtmp->minvent) saveobjchn(fd,mtmp->minvent);
  156.         free((char *) mtmp);
  157.         mtmp = mtmp2;
  158.     }
  159.     bwrite(fd, (char *) &minusone, sizeof(int));
  160. }
  161. #else
  162.  
  163. savemonchn(fd,mtmp)
  164. register fd;
  165. register struct monst *mtmp;
  166. {
  167.     register struct monst *mtmp2;
  168.     unsigned xl;
  169.     int minusone = -1;
  170.     struct permonst *monbegin = &mons[0];
  171.  
  172.     bwrite(fd, (char *) &monbegin, sizeof(monbegin));
  173.  
  174.     while(mtmp) {
  175.         mtmp2 = mtmp->nmon;
  176.         xl = mtmp->mxlth + mtmp->mnamelth;
  177.         bwrite(fd, (char *) &xl, sizeof(int));
  178.         bwrite(fd, (char *) mtmp, xl + sizeof(struct monst));
  179.         if(mtmp->minvent) saveobjchn(fd,mtmp->minvent);
  180.         free((char *) mtmp);
  181.         mtmp = mtmp2;
  182.     }
  183.     bwrite(fd, (char *) &minusone, sizeof(int));
  184. }
  185. #endif MSDOS
  186.  
  187. savegoldchn(fd,gold)
  188. register fd;
  189. register struct gold *gold;
  190. {
  191.     register struct gold *gold2;
  192.     while(gold) {
  193.         gold2 = gold->ngold;
  194.         bwrite(fd, (char *) gold, sizeof(struct gold));
  195.         free((char *) gold);
  196.         gold = gold2;
  197.     }
  198.     bwrite(fd, nul, sizeof(struct gold));
  199. }
  200.  
  201. savetrapchn(fd,trap)
  202. register fd;
  203. register struct trap *trap;
  204. {
  205.     register struct trap *trap2;
  206.     while(trap) {
  207.         trap2 = trap->ntrap;
  208.         bwrite(fd, (char *) trap, sizeof(struct trap));
  209.         free((char *) trap);
  210.         trap = trap2;
  211.     }
  212.     bwrite(fd, nul, sizeof(struct trap));
  213. }
  214.  
  215. getlev(fd,pid,lev)
  216. int fd,pid;
  217. xchar lev;
  218. {
  219.     register struct gold *gold;
  220.     register struct trap *trap;
  221. #ifndef NOWORM
  222.     register struct wseg *wtmp;
  223. #endif NOWORM
  224.     register tmp;
  225.     long omoves;
  226.     int hpid;
  227.     xchar dlvl;
  228. #ifdef TOS
  229.     short tlev;
  230. #endif
  231.  
  232. #ifdef MSDOS
  233. #ifndef TOS
  234.     setmode(fd,O_BINARY);
  235. #endif
  236. #endif MSDOS
  237.     /* First some sanity checks */
  238.     mread(fd, (char *) &hpid, sizeof(hpid));
  239. #ifdef TOS
  240.     mread(fd, (char *) &tlev, sizeof(tlev));
  241.     dlvl=tlev&0xff;
  242. #else
  243.     mread(fd, (char *) &dlvl, sizeof(dlvl));
  244. #endif
  245.     if((pid && pid != hpid) || (lev && dlvl != lev)) {
  246.         pline("Strange, this map is not as I remember it.");
  247.         pline("Somebody is trying some trickery here ...");
  248.         pline("This game is void ...");
  249.         done("tricked");
  250.     }
  251.  
  252.     fgold = 0;
  253.     ftrap = 0;
  254.     mread(fd, (char *) levl, sizeof(levl));
  255.     mread(fd, (char *)&omoves, sizeof(omoves));
  256.     mread(fd, (char *)&xupstair, sizeof(xupstair));
  257.     mread(fd, (char *)&yupstair, sizeof(yupstair));
  258.     mread(fd, (char *)&xdnstair, sizeof(xdnstair));
  259.     mread(fd, (char *)&ydnstair, sizeof(ydnstair));
  260.  
  261.     fmon = restmonchn(fd);
  262.  
  263.     /* regenerate animals while on another level */
  264.     { long tmoves = (moves > omoves) ? moves-omoves : 0;
  265.       register struct monst *mtmp, *mtmp2;
  266.       extern char genocided[];
  267.       for(mtmp = fmon; mtmp; mtmp = mtmp2) {
  268.         long newhp;        /* tmoves may be very large */
  269.  
  270.         mtmp2 = mtmp->nmon;
  271.         if(index(genocided, mtmp->data->mlet)) {
  272.             mondead(mtmp);
  273.             continue;
  274.         }
  275.  
  276.         if(mtmp->mtame && tmoves > 250) {
  277.             mtmp->mtame = 0;
  278.             mtmp->mpeaceful = 0;
  279.         }
  280.  
  281.         newhp = mtmp->mhp +
  282.             (index(MREGEN, mtmp->data->mlet) ? tmoves : tmoves/20);
  283.         if(newhp > mtmp->mhpmax)
  284.             mtmp->mhp = mtmp->mhpmax;
  285.         else
  286.             mtmp->mhp = newhp;
  287.       }
  288.     }
  289.  
  290.     setgd();
  291.     gold = newgold();
  292.     mread(fd, (char *)gold, sizeof(struct gold));
  293.     while(gold->gx) {
  294.         gold->ngold = fgold;
  295.         fgold = gold;
  296.         gold = newgold();
  297.         mread(fd, (char *)gold, sizeof(struct gold));
  298.     }
  299.     free((char *) gold);
  300.     trap = newtrap();
  301.     mread(fd, (char *)trap, sizeof(struct trap));
  302.     while(trap->tx) {
  303.         trap->ntrap = ftrap;
  304.         ftrap = trap;
  305.         trap = newtrap();
  306.         mread(fd, (char *)trap, sizeof(struct trap));
  307.     }
  308.     free((char *) trap);
  309.     fobj = restobjchn(fd);
  310.     billobjs = restobjchn(fd);
  311.     rest_engravings(fd);
  312. #ifndef QUEST
  313.     mread(fd, (char *)rooms, sizeof(rooms));
  314.     mread(fd, (char *)doors, sizeof(doors));
  315. #endif QUEST
  316. #ifndef NOWORM
  317.     mread(fd, (char *)wsegs, sizeof(wsegs));
  318.     for(tmp = 1; tmp < 32; tmp++) if(wsegs[tmp]){
  319.         wheads[tmp] = wsegs[tmp] = wtmp = newseg();
  320.         while(1) {
  321.             mread(fd, (char *)wtmp, sizeof(struct wseg));
  322.             if(!wtmp->nseg) break;
  323.             wheads[tmp]->nseg = wtmp = newseg();
  324.             wheads[tmp] = wtmp;
  325.         }
  326.     }
  327.     mread(fd, (char *)wgrowtime, sizeof(wgrowtime));
  328. #endif NOWORM
  329. }
  330.  
  331. mread(fd, buf, len)
  332. register fd;
  333. register char *buf;
  334. register unsigned len;
  335. {
  336.     register int rlen;
  337.     extern boolean restoring;
  338.  
  339.     rlen = read(fd, buf, (int) len);
  340.     if(rlen != len){
  341.         pline("Read %d instead of %u bytes.\n", rlen, len);
  342.         if(restoring) {
  343.             (void) unlink(SAVEF);
  344.             error("Error restoring old game.");
  345.         }
  346.         panic("Error reading level file.");
  347.     }
  348. }
  349.  
  350. mklev()
  351. {
  352.     extern boolean in_mklev;
  353.  
  354.     if(getbones()) return;
  355.  
  356.     in_mklev = TRUE;
  357.     makelevel();
  358.     in_mklev = FALSE;
  359. }
  360.